import { StorageManager } from '../utils/storage.js';

export class SessionManager {
  constructor() {
    this.storage = new StorageManager();
    this.sessions = new Map();
    this.tabSessions = new Map(); // tabId -> sessionId 映射
    this.activeSessionId = null;
  }

  async init() {
    try {
      console.log('SessionManager: 开始初始化');
      
      // 从存储中加载会话数据
      const data = await this.storage.get(['sessions', 'tabSessions', 'activeSessionId']);
      console.log('SessionManager: 从存储加载的数据:', data);
      
      if (data.sessions) {
        for (const [id, session] of Object.entries(data.sessions)) {
          this.sessions.set(id, session);
        }
        console.log('SessionManager: 加载了', Object.keys(data.sessions).length, '个会话');
      }
      
      if (data.tabSessions) {
        for (const [tabId, sessionId] of Object.entries(data.tabSessions)) {
          this.tabSessions.set(parseInt(tabId), sessionId);
        }
        console.log('SessionManager: 加载了', Object.keys(data.tabSessions).length, '个标签页会话映射');
      }
      
      this.activeSessionId = data.activeSessionId || null;
      console.log('SessionManager: 活动会话ID:', this.activeSessionId);
      console.log('SessionManager: 初始化完成');
    } catch (error) {
      console.error('SessionManager: 初始化失败:', error);
      throw error;
    }
  }

  async createSession(config = {}) {
    try {
      console.log('SessionManager: 开始创建会话，配置:', config);
      
      const sessionId = this.generateSessionId();
      const session = {
        id: sessionId,
        name: config.name || `会话 ${sessionId.slice(-4)}`,
        color: config.color || this.getRandomColor(),
        proxy: config.proxy || null,
        userAgent: config.userAgent || null,
        fingerprintProtection: config.fingerprintProtection || false,
        fingerprintConfig: config.fingerprintConfig || {
          protectCanvas: true,
          protectWebGL: true,
          protectAudio: true,
          blockWebRTC: true,
          showIndicator: true
        },
        cookies: {},
        localStorage: {},
        sessionStorage: {},
        tabs: [],
        createdAt: Date.now(),
        lastUsed: Date.now()
      };

      console.log('SessionManager: 会话对象创建完成:', session);
      
      this.sessions.set(sessionId, session);
      console.log('SessionManager: 会话已添加到内存，当前会话数量:', this.sessions.size);
      
      await this.saveToStorage();
      console.log('SessionManager: 会话已保存到存储');
      
      return session;
    } catch (error) {
      console.error('SessionManager: 创建会话失败:', error);
      throw error;
    }
  }

  async createDefaultSession() {
    const defaultSession = await this.createSession({
      name: '默认会话',
      color: '#4285f4',
      fingerprintProtection: false
    });
    
    this.activeSessionId = defaultSession.id;
    await this.saveToStorage();
    
    return defaultSession;
  }

  async createQuickSession() {
    return await this.createSession({
      name: `快速会话 ${Date.now()}`,
      color: this.getRandomColor(),
      fingerprintProtection: true
    });
  }

  async deleteSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) return;

    // 关闭会话中的所有标签页
    for (const tabId of session.tabs) {
      try {
        await chrome.tabs.remove(tabId);
      } catch (error) {
        console.warn('Failed to close tab:', tabId, error);
      }
    }

    // 清理标签页映射
    for (const [tabId, sId] of this.tabSessions.entries()) {
      if (sId === sessionId) {
        this.tabSessions.delete(tabId);
      }
    }

    // 删除会话
    this.sessions.delete(sessionId);
    
    // 如果删除的是当前活动会话，切换到默认会话
    if (this.activeSessionId === sessionId) {
      const remainingSessions = Array.from(this.sessions.values());
      this.activeSessionId = remainingSessions.length > 0 ? remainingSessions[0].id : null;
    }

    await this.saveToStorage();
  }

  async switchToSession(sessionId, currentTabId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error('找不到会话');

    // 更新当前标签页的会话归属
    this.tabSessions.set(currentTabId, sessionId);
    
    // 添加标签页到会话
    if (!session.tabs.includes(currentTabId)) {
      session.tabs.push(currentTabId);
    }

    // 设置为活动会话
    this.activeSessionId = sessionId;
    session.lastUsed = Date.now();

    await this.saveToStorage();
    
    // 通知内容脚本会话已切换
    try {
      await chrome.tabs.sendMessage(currentTabId, {
        action: 'sessionSwitched',
        sessionId: sessionId,
        session: session
      });
    } catch (error) {
      console.warn('SessionManager: 通知内容脚本失败:', error);
    }
    
    // 重新加载页面以应用新的会话环境
    await chrome.tabs.reload(currentTabId);
  }

  async openUrlInSession(url, sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error('找不到会话');

    console.log('SessionManager: 在会话中打开URL:', url, '会话ID:', sessionId);

    // 创建新标签页
    const tab = await chrome.tabs.create({
      url: url,
      active: true
    });

    // 关联标签页和会话
    this.tabSessions.set(tab.id, sessionId);
    session.tabs.push(tab.id);
    session.lastUsed = Date.now();

    await this.saveToStorage();
    
    // 如果不是新标签页，等待页面加载后清除数据
    if (url !== 'chrome://newtab/') {
      setTimeout(async () => {
        try {
          // 清除新标签页的所有数据
          await this.clearTabData(tab.id, url);
          
          // 通知内容脚本应用新会话
          await chrome.tabs.sendMessage(tab.id, {
            action: 'sessionSwitched',
            sessionId: sessionId,
            session: session
          });
        } catch (error) {
          console.warn('SessionManager: 处理新标签页失败:', error);
        }
      }, 1500);
    } else {
      // 对于新标签页，直接通知内容脚本
      setTimeout(async () => {
        try {
          await chrome.tabs.sendMessage(tab.id, {
            action: 'sessionSwitched',
            sessionId: sessionId,
            session: session
          });
        } catch (error) {
          console.warn('SessionManager: 通知新标签页内容脚本失败:', error);
        }
      }, 1000);
    }
    
    return tab;
  }

  // 在当前页面基础上创建新会话
  async createSessionFromCurrentPage(currentTabId, config = {}) {
    try {
      console.log('SessionManager: 从当前页面创建新会话, tabId:', currentTabId);
      
      // 获取当前标签页信息
      const currentTab = await chrome.tabs.get(currentTabId);
      console.log('SessionManager: 当前标签页信息:', currentTab);
      
      // 创建新会话
      const newSession = await this.createSession(config);
      console.log('SessionManager: 新会话创建成功:', newSession);
      
      // 彻底清除目标域名的所有数据
      console.log('SessionManager: 开始彻底清除目标域名数据');
      await this.clearDomainData(currentTab.url);
      
      // 直接创建目标页面，不使用about:blank
      const newTab = await chrome.tabs.create({
        url: currentTab.url,
        active: true
      });
      
      console.log('SessionManager: 新标签页创建成功:', newTab);
      
      // 关联新标签页到新会话
      this.tabSessions.set(newTab.id, newSession.id);
      newSession.tabs.push(newTab.id);
      newSession.lastUsed = Date.now();
      
      await this.saveToStorage();
      
      // 等待一小段时间确保标签页准备好
      await new Promise(resolve => setTimeout(resolve, 200));
      
      // 设置标签页更新监听器
      const tabUpdateListener = async (tabId, changeInfo, tab) => {
        if (tabId === newTab.id) {
          if (changeInfo.status === 'loading' && changeInfo.url) {
            console.log('SessionManager: 页面开始加载，再次确保数据清除');
            try {
              // 再次清除数据，确保绝对干净
              await this.clearDomainData(currentTab.url);
            } catch (error) {
              console.warn('SessionManager: 加载时清除数据失败:', error);
            }
          } else if (changeInfo.status === 'complete' && changeInfo.url) {
            console.log('SessionManager: 页面加载完成，通知内容脚本');
            
            // 等待一小段时间确保内容脚本准备好
            setTimeout(async () => {
              try {
                await chrome.tabs.sendMessage(newTab.id, {
                  action: 'sessionSwitched',
                  sessionId: newSession.id,
                  session: newSession
                });
              } catch (error) {
                console.warn('SessionManager: 通知新标签页内容脚本失败:', error);
              }
            }, 500);
            
            // 移除监听器
            chrome.tabs.onUpdated.removeListener(tabUpdateListener);
          }
        }
      };
      
      // 添加标签页更新监听器
      chrome.tabs.onUpdated.addListener(tabUpdateListener);
      
      // 设置超时移除监听器，防止内存泄漏
      setTimeout(() => {
        chrome.tabs.onUpdated.removeListener(tabUpdateListener);
      }, 30000); // 30秒后自动移除
      
      return {
        session: newSession,
        tab: newTab
      };
    } catch (error) {
      console.error('SessionManager: 从当前页面创建会话失败:', error);
      throw error;
    }
  }

  async updateSession(sessionId, config) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error('找不到会话');

    // 更新会话配置
    Object.assign(session, config);
    session.lastUsed = Date.now();

    await this.saveToStorage();
  }

  async getSessionByTabId(tabId) {
    const sessionId = this.tabSessions.get(tabId);
    return sessionId ? this.sessions.get(sessionId) : null;
  }

  async getAllSessions() {
    console.log('SessionManager: 获取所有会话，内存中会话数量:', this.sessions.size);
    const sessions = Array.from(this.sessions.values());
    
    console.log('SessionManager: 会话详情:');
    sessions.forEach((session, index) => {
      console.log(`  ${index + 1}. ID: ${session.id}, 名称: ${session.name}, 颜色: ${session.color}`);
    });
    
    const sortedSessions = sessions.sort((a, b) => b.lastUsed - a.lastUsed);
    console.log('SessionManager: 返回', sortedSessions.length, '个会话');
    return sortedSessions;
  }

  async getActiveSession() {
    return this.activeSessionId ? this.sessions.get(this.activeSessionId) : null;
  }

  async setActiveSession(sessionId) {
    if (this.sessions.has(sessionId)) {
      this.activeSessionId = sessionId;
      const session = this.sessions.get(sessionId);
      session.lastUsed = Date.now();
      await this.saveToStorage();
    }
  }

  async setSessionCookie(sessionId, cookieString) {
    const session = this.sessions.get(sessionId);
    if (!session) return;

    try {
      // 解析Cookie字符串
      const cookieParts = cookieString.split(';');
      const [nameValue] = cookieParts[0].split('=');
      const cookieName = nameValue.trim();
      const cookieValue = cookieParts[0].split('=').slice(1).join('=').trim();

      // 获取当前域名（需要通过tabs API获取）
      const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
      if (tabs.length > 0 && tabs[0].url) {
        const url = new URL(tabs[0].url);
        const domain = url.hostname;

        // 存储Cookie到会话中
        if (!session.cookies) {
          session.cookies = {};
        }
        
        if (!session.cookies[domain]) {
          session.cookies[domain] = {};
        }
        
        session.cookies[domain][cookieName] = {
          value: cookieValue,
          domain: domain,
          path: '/',
          secure: cookieString.includes('Secure'),
          httpOnly: cookieString.includes('HttpOnly'),
          sameSite: cookieString.includes('SameSite=Strict') ? 'strict' : 
                   cookieString.includes('SameSite=Lax') ? 'lax' : 'no_restriction'
        };

        await this.saveToStorage();
        console.log('SessionManager: Cookie已保存到会话', sessionId, '域名:', domain, 'Cookie:', cookieName);
      }
    } catch (error) {
      console.error('SessionManager: 设置会话Cookie失败:', error);
    }
  }

  async getSessionCookies(sessionId, domain) {
    const session = this.sessions.get(sessionId);
    if (!session || !session.cookies || !session.cookies[domain]) {
      return '';
    }

    const cookies = session.cookies[domain];
    const cookieStrings = [];

    for (const [name, cookie] of Object.entries(cookies)) {
      cookieStrings.push(`${name}=${cookie.value}`);
    }

    return cookieStrings.join('; ');
  }

  // 清除指定域名的所有数据（Cookie、localStorage、sessionStorage）
  async clearDomainData(url) {
    try {
      console.log('SessionManager: 开始彻底清除域名数据, URL:', url);
      
      // 获取域名
      const urlObj = new URL(url);
      const domain = urlObj.hostname;
      const origin = urlObj.origin;
      
      console.log('SessionManager: 清除域名:', domain, '源:', origin);
      
      // 1. 清除该域名的所有Cookie（包括HttpOnly）
      const mainCookies = await chrome.cookies.getAll({ domain: domain });
      console.log('SessionManager: 找到主域名Cookie', mainCookies.length, '个');
      
      for (const cookie of mainCookies) {
        try {
          await chrome.cookies.remove({
            url: `${cookie.secure ? 'https' : 'http'}://${cookie.domain}${cookie.path}`,
            name: cookie.name
          });
          console.log('SessionManager: 已清除主域名Cookie:', cookie.name);
        } catch (error) {
          console.warn('SessionManager: 清除主域名Cookie失败:', cookie.name, error);
        }
      }
      
      // 2. 清除子域名Cookie
      const subdomainCookies = await chrome.cookies.getAll({ domain: '.' + domain });
      console.log('SessionManager: 找到子域名Cookie', subdomainCookies.length, '个');
      
      for (const cookie of subdomainCookies) {
        try {
          await chrome.cookies.remove({
            url: `${cookie.secure ? 'https' : 'http'}://${cookie.domain}${cookie.path}`,
            name: cookie.name
          });
          console.log('SessionManager: 已清除子域名Cookie:', cookie.name);
        } catch (error) {
          console.warn('SessionManager: 清除子域名Cookie失败:', cookie.name, error);
        }
      }
      
      // 3. 清除所有浏览器存储数据
      try {
        await chrome.browsingData.remove({
          origins: [origin]
        }, {
          localStorage: true,
          sessionStorage: true,
          indexedDB: true,
          webSQL: true,
          cacheStorage: true,
          cache: true
        });
        console.log('SessionManager: 已清除浏览器存储数据');
      } catch (error) {
        console.warn('SessionManager: 清除浏览器存储数据失败:', error);
      }
      
      // 4. 额外等待确保数据清除完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      console.log('SessionManager: 域名数据彻底清除完成');
    } catch (error) {
      console.error('SessionManager: 清除域名数据失败:', error);
    }
  }

  // 清除标签页的所有数据（Cookie、localStorage、sessionStorage）
  async clearTabData(tabId, url) {
    try {
      console.log('SessionManager: 开始清除标签页数据, tabId:', tabId);
      
      // 先清除域名数据
      await this.clearDomainData(url);
      
      // 注入脚本清除localStorage和sessionStorage
      await chrome.scripting.executeScript({
        target: { tabId: tabId },
        func: () => {
          // 清除所有存储数据
          try {
            localStorage.clear();
            sessionStorage.clear();
            
            // 清除所有Cookie（客户端可访问的）
            document.cookie.split(";").forEach(function(c) { 
              document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); 
            });
            
            console.log('SessionBox: 标签页数据已清除');
          } catch (error) {
            console.warn('SessionBox: 清除数据时出错:', error);
          }
        }
      });
      
      console.log('SessionManager: 标签页数据清除完成');
    } catch (error) {
      console.error('SessionManager: 清除标签页数据失败:', error);
    }
  }

  async removeTabFromSession(tabId) {
    const sessionId = this.tabSessions.get(tabId);
    if (sessionId) {
      const session = this.sessions.get(sessionId);
      if (session) {
        session.tabs = session.tabs.filter(id => id !== tabId);
        await this.saveToStorage();
      }
      this.tabSessions.delete(tabId);
    }
  }

  generateSessionId() {
    // 使用更强的随机性和时间戳确保唯一性
    const timestamp = Date.now();
    const random1 = Math.random().toString(36).substr(2, 9);
    const random2 = Math.random().toString(36).substr(2, 9);
    const id = `session_${timestamp}_${random1}_${random2}`;
    console.log('SessionManager: 生成会话ID:', id);
    return id;
  }

  getRandomColor() {
    const colors = [
      '#4285f4', '#ea4335', '#fbbc04', '#34a853', 
      '#ff6d01', '#9c27b0', '#00bcd4', '#795548'
    ];
    return colors[Math.floor(Math.random() * colors.length)];
  }

  // 保存会话存储数据
  async saveSessionStorage(sessionId, type, data) {
    const session = this.sessions.get(sessionId);
    if (!session) return;
    
    if (!session.storageData) {
      session.storageData = {};
    }
    
    session.storageData[type] = data;
    await this.saveToStorage();
    console.log('SessionManager: 会话存储已保存:', sessionId, type);
  }
  
  // 获取会话存储数据
  async getSessionStorage(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session || !session.storageData) {
      return {
        localStorage: {},
        sessionStorage: {}
      };
    }
    
    return session.storageData;
  }
  
  // 保存会话Cookie数据
  async saveSessionCookies(sessionId, cookies) {
    const session = this.sessions.get(sessionId);
    if (!session) return;
    
    session.cookieData = cookies;
    await this.saveToStorage();
    console.log('SessionManager: 会话Cookie已保存:', sessionId, cookies);
  }
  
  // 获取会话Cookie数据（新版本）
  async getSessionCookies(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session || !session.cookieData) {
      return {};
    }
    
    return session.cookieData;
  }

  async saveToStorage() {
    try {
      console.log('SessionManager: 开始保存到存储');
      console.log('SessionManager: 当前内存中的会话数量:', this.sessions.size);
      
      // 详细记录要保存的会话
      const sessionsData = {};
      for (const [id, session] of this.sessions.entries()) {
        sessionsData[id] = session;
        console.log(`SessionManager: 准备保存会话 ${id}:`, {
          name: session.name,
          color: session.color,
          createdAt: session.createdAt
        });
      }
      
      const data = {
        sessions: sessionsData,
        tabSessions: Object.fromEntries(this.tabSessions),
        activeSessionId: this.activeSessionId
      };
      
      console.log('SessionManager: 准备保存的数据:', {
        sessionsCount: Object.keys(data.sessions).length,
        sessionIds: Object.keys(data.sessions),
        tabSessionsCount: Object.keys(data.tabSessions).length,
        activeSessionId: data.activeSessionId
      });
      
      await this.storage.set(data);
      console.log('SessionManager: 数据保存成功');
      
      // 验证保存是否成功
      const savedData = await this.storage.get(['sessions']);
      console.log('SessionManager: 验证保存结果，存储中的会话数量:', 
        savedData.sessions ? Object.keys(savedData.sessions).length : 0);
        
    } catch (error) {
      console.error('SessionManager: 保存数据失败:', error);
      throw error;
    }
  }
} 